package com.ddd.infrastructure.persistence.inmemory;


import com.ddd.domain.model.product.ProductEntity;
import com.ddd.domain.model.product.ProductRepository;
import com.ddd.domain.share.TrackingId;

import java.util.*;

/**
 * CargoRepositoryInMem implement the CargoRepository interface but is a test
 * class not intended for usage in real application.
 * <p>
 * It setup a simple local hash with a number of Cargo's with TrackingId as key
 * defined at compile time.
 * <p>
 */
public class ProductRepositoryInMem implements ProductRepository {

    private Map<String, ProductEntity> productDb;
//    private HandlingEventRepository handlingEventRepository;

    /**
     * Constructor.
     */
    public ProductRepositoryInMem() {
        productDb = new HashMap<>();
    }

    public ProductEntity find(final TrackingId skuId) {
        return productDb.get(skuId.idString());
    }

    public void save(final ProductEntity product) {
        productDb.put(product.trackingId().idString(), product);
    }

    public TrackingId nextTrackingId() {
        String random = UUID.randomUUID().toString().toUpperCase();
        return new TrackingId(
                random.substring(0, random.indexOf("-"))
        );
    }

    @Override
    public boolean update(ProductEntity productEntity) {
        productDb.put(productEntity.trackingId().idString(),productEntity);
        return true;
    }

    public List<ProductEntity> findAll() {
        return new ArrayList<>(productDb.values());
    }

//    public void init() throws Exception {
//        final TrackingId xyz = new TrackingId("XYZ");
//        final ProductEntity cargoXYZ = createCargoWithDeliveryHistory(
//                xyz, STOCKHOLM, MELBOURNE, handlingEventRepository.lookupHandlingHistoryOfCargo(xyz));
//        cargoDb.put(xyz.idString(), cargoXYZ);
//
//        final TrackingId zyx = new TrackingId("ZYX");
//        final Cargo cargoZYX = createCargoWithDeliveryHistory(
//                zyx, MELBOURNE, STOCKHOLM, handlingEventRepository.lookupHandlingHistoryOfCargo(zyx));
//        cargoDb.put(zyx.idString(), cargoZYX);
//
//        final TrackingId abc = new TrackingId("ABC");
//        final Cargo cargoABC = createCargoWithDeliveryHistory(
//                abc, STOCKHOLM, HELSINKI, handlingEventRepository.lookupHandlingHistoryOfCargo(abc));
//        cargoDb.put(abc.idString(), cargoABC);
//
//        final TrackingId cba = new TrackingId("CBA");
//        final Cargo cargoCBA = createCargoWithDeliveryHistory(
//                cba, HELSINKI, STOCKHOLM, handlingEventRepository.lookupHandlingHistoryOfCargo(cba));
//        cargoDb.put(cba.idString(), cargoCBA);
//    }

//    public void setHandlingEventRepository(final HandlingEventRepository handlingEventRepository) {
//        this.handlingEventRepository = handlingEventRepository;
//    }

//    public static ProductEntity createCargoWithDeliveryHistory(TrackingId trackingId,
//                                                       Location origin,
//                                                       Location destination,
//                                                       HandlingHistory handlingHistory) {
//
//        final RouteSpecification routeSpecification = new RouteSpecification(origin, destination, new Date());
//        final Cargo cargo = new Cargo(trackingId, routeSpecification);
//        cargo.deriveDeliveryProgress(handlingHistory);
//
//        return cargo;
//    }
}
